////////////////////////////////////////////////////////////////////////
// Class gewTextureManager
function gewTextureManager(game)
{
  this.textureList = {};
  this.textureAtlasList = {};
  this.game = game;
  this.gl = game.gl;
}
gewTextureManager.prototype.removeTexture = function(name)
{
  var tex = this.textureList[name];
  if(!tex)
    return;
  this.gl.deleteTexture(tex.glName);
  delete this.textureList[name];
}

gewTextureManager.prototype.getTexture = function(name)
{
  return this.textureList[name];
}
gewTextureManager.prototype.getAtlas = function(name)
{
  return this.textureAtlasList[name];
}

gewTextureManager.prototype.loadTexture = function(name, url, format, textureParameter, isGenerateMipmap,isFlipY,isPremultipliedAlpha)
{
  var gl = this.gl;
  var texture = new gewTexture(gl,gl.TEXTURE_2D);
  texture.name = name;
  this.textureList[name] = texture;
  if(format!=undefined)
    texture.format = format;
  if(textureParameter!=undefined)
    texture.setTextureParam(textureParameter);
  if(isGenerateMipmap!=undefined)
    texture.isMipmaped = isGenerateMipmap;
  if(isFlipY!=undefined)
    texture.isFlipY = isFlipY;
  if(isPremultipliedAlpha!=undefined)
    texture.isPremultipliedAlpha = isPremultipliedAlpha;
  return texture;
}

gewTextureManager.prototype.createTextureAtlasRequest = function(name, url, textureList,queryItem)
{
  var gl = this.gl;
  var atlas = new gewTextureAtlas();
  atlas.textureList = textureList;
  this.textureAtlasList[name] = atlas;
  var xmlhttp;
  xmlhttp = new XMLHttpRequest();
  xmlhttp.onreadystatechange = function()
  {
    if (xmlhttp.readyState == 4) 
    {
      if (xmlhttp.status == 200 || xmlhttp.status == 0) 
      {
        queryItem.status = GEW_DOWNLOAD_STATUS_FINISHED;
        atlas.readSubTextureInfo(xmlhttp.responseText);
        atlas.isReady = true;
      } 
      else 
      {
        alert("gewTextureManager::loadTextureAtlas:Error when load " + url + " !");
      }
    }
  }
  xmlhttp.open("GET", url, true);
  //xmlhttp.send(null);
  return xmlhttp;
}

gewTextureManager.prototype.loadCubeMap = function(name, urls, textureParameter, isGenerateMipmap,isFlipY)
{
  var gl = this.gl;
  var texture = new gewTexture();
  texture.glName = gl.createTexture();
  this.textureList[name] = texture;
  var imgs = [];
  for(var i=0;i<6;i++)
  {
    imgs[i] = new Image();
    imgs[i].faceNum = i;
    imgs[i].onload = function()
    {
      //alert("LOADED!");
      texture.loadCubeMapIntoGLMemory(gl, this,this.faceNum, textureParameter, isGenerateMipmap,isFlipY);
      delete imgs[this.faceNum];
    }
    imgs[i].src = urls[i];
  }
}

function gewTextureParameter(magFilter, minFilter, wrapS, wrapT)
{
  if(magFilter)
    this.magFilter = magFilter;
  if(minFilter)
    this.minFilter = minFilter;
  if(wrapS)
    this.wrapS = wrapS;
  if(wrapT)
    this.wrapT = wrapT;
}
function gewTexture(gl,type)
{
  this.type = type;
  this.gl = gl; 
  this.name = null;
  this.glName = gl.createTexture();
  this.format = gl.RGBA;
  this.width = 0;
  this.height = 0;
  this.url = null;
  this.isReady = false;
  this.loadedFace = 0;// use for cubemap load tracking
  this.urls = [] ;// use for cubemap
  this.isMipmaped = true;
  this.isFlipY = true;
  this.isPremultipliedAlpha = true;
}
gewTexture.prototype.setTextureParam = function(textureParameter)
{
  var gl =this.gl
  if(this.type==gl.TEXTURE_2D)
  {
    var type = this.type;
    gl.bindTexture(type, this.glName);
    if (!textureParameter) 
    {
      gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
      gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
      gl.texParameteri(type, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      gl.texParameteri(type, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    }
    else 
    {
      if (textureParameter.magFilter) 
        gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, textureParameter.magFilter);
      else
        gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        
      if (textureParameter.minFilter) 
        gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, textureParameter.minFilter);
      else
        gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
      
      if (textureParameter.wrapS) 
        gl.texParameteri(type, gl.TEXTURE_WRAP_S, textureParameter.wrapS);
      else
        gl.texParameteri(type, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      
      if (textureParameter.wrapT) 
        gl.texParameteri(type, gl.TEXTURE_WRAP_T, textureParameter.wrapT);
      else
        gl.texParameteri(type, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    }
  }
}
gewTexture.prototype.loadIntoGLMemory = function(image)
{
  var gl = this.gl;
  this.width = image.width;
  this.height = image.height;
  this.url = image.src;
  this.isReady = true;
  gl.bindTexture(gl.TEXTURE_2D, this.glName);
  /*
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,this.isFlipY);
  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this.isPremultipliedAlpha);    
  gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, gl.UNSIGNED_BYTE, image);
  */
  gl.texImage2D(gl.TEXTURE_2D, 0, image,this.isFlipY,this.isPremultipliedAlpha);
  if (this.isMipmaped==true) 
    gl.generateMipmap(gl.TEXTURE_2D);
  gl.bindTexture(gl.TEXTURE_2D, null);
}

gewTexture.prototype.loadCubeMapIntoGLMemory = function(gl, image,face, textureParameter, isGenerateMipmap,isFlipY)
{
  this.urls[face] = image.src;
  this.loadedFace++;
  gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glName);
  if( isFlipY==false)
    gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X+face, 0, image);
  else
    gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X+face, 0, image,true);
    
  if(this.loadedFace==6)
  {
    this.type = gl.TEXTURE_CUBE_MAP;
    this.width = image.width;
    this.height = image.height;
    if (isGenerateMipmap!= false) 
    {
      gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
    }
    if (!textureParameter) 
    {
      gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
      gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
      gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    }
    else 
    {
      if (textureParameter.magFilter) 
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, textureParameter.magFilter);
      else
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        
      if (textureParameter.minFilter) 
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, textureParameter.minFilter);
      else
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
      
      if (textureParameter.wrapS) 
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, textureParameter.wrapS);
      else
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      
      if (textureParameter.wrapT) 
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, textureParameter.wrapT);
      else
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    }
    this.isReady = true;
  }
  gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
}


////////////////////////////////////////////////////////////////
// Texture altas
function gewSubTexture()
{
  this.type = null;
  this.woffset = 0;
  this.hoffet = 0;
  this.doffset = 0; // depth offset, only for 3D subtex
  this.width = 0;
  this.height = 0;
  this.mainTexture = null;
}

function gewTextureAtlas()
{
  this.textureList = [];
  this.subTexList = {};
  this.isSubTexReady = false;
}

gewTextureAtlas.prototype.readSubTextureInfo = function(str)
{
  var lines = str.split('\n');
  var reg = /[\S]+/gmi;
  var mainTex = this.textureList;
  for (var i = 0, len = lines.length; i < len; i++) 
  {
    var line = lines[i];
    var c0 = line.charAt(0);
    if (c0!=' '&&c0!='#'&&c0!='\n'&&line.length>5) 
    {
      reg.compile(reg);
      var token = reg.exec(line);
      var subTex = new gewSubTexture;
      this.subTexList[token[0]] = subTex;
      token = reg.exec(line);
      token = reg.exec(line);
      var idx = parseInt(token[0].slice(0, token[0].length - 1));
      subTex.mainTexture = mainTex[idx];
      token = reg.exec(line);
      subTex.type = token[0].slice(0, token[0].length - 1);
      ;
      token = reg.exec(line);
      subTex.woffset = parseFloat(token[0].slice(0, token[0].length - 1));
      ;
      token = reg.exec(line);
      subTex.hoffset = parseFloat(token[0].slice(0, token[0].length - 1));
      ;
      token = reg.exec(line);
      subTex.doffset = parseFloat(token[0].slice(0, token[0].length - 1));
      ;
      token = reg.exec(line);
      subTex.width = parseFloat(token[0].slice(0, token[0].length - 1));
      ;
      token = reg.exec(line);
      subTex.height = parseFloat(token[0].slice(0, token[0].length - 1));
      ;
    }
  }
}
